/**
 * 
 *  
 * Author: Matthias Van Eeghem <matthias@van-eeghem.com>
 * All rights reserved.
 * 
 */

package com.bomberman;

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;

import javax.swing.*;

import com.bomberman.connection.ConnectionManager;
import com.bomberman.gui.JoinGame;
import com.bomberman.player.PlayerManager;

@SuppressWarnings("serial")
public class Main extends JFrame implements ActionListener
{
	// The buttons on the menu
	/**
	 * The host game button, allows a user to host a game.
	 */
	private static JButton hostGameButton = new JButton("Host game");
	/**
	 * The join game button, allows a user to join active sessions. 
	 */
	private static JButton joinGameButton = new JButton("Join game");
	/**
	 * The options button, allows users to change their key configuration & name.
	 */
	private static JButton optionsButton = new JButton("Options");
	/**
	 * Exit button, exits the application
	 */
	private static JButton exitButton = new JButton("Exit");
	/**
	 * Holds the JFrame the game is running on	
	 */
    private JFrame gameFrame = null;
	/**
	 * Holds the "Join game frame"
	 */
    public JFrame joinGameFrame = null;
    /**
     * Holds the connection manager for this client.
     */
    private volatile ConnectionManager connectionManager = null;
    
	public static String playerName = "Player" + (char) (new java.util.Random().nextInt(25) + 95);
	
	
    /**
     * Constructor of the Main class. This method initialises the menu.
     */
	public Main()
	{
	    // Get the user's screen resolution
		Dimension screenDimensions = Toolkit.getDefaultToolkit().getScreenSize();

		// Default close operation is exit
	    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    
	    // Set the game title
	    setTitle("Bomberman");
	    
		// Set the startup location and the size for the application
	    setBounds((screenDimensions.width / 2) - 400, (screenDimensions.height / 2) - 300, 800, 600);

	    // Container for the JPanel (and thus the vertical box to be on)
	    Container pane = getContentPane();
	   
	    // Create a vertical box
	    Box verticalBox;
	    verticalBox = Box.createVerticalBox();
	    
	    // Set the layout
	    pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
	    
	    // Align all buttons to the center
	    hostGameButton.setAlignmentX(Component.CENTER_ALIGNMENT);
	    joinGameButton.setAlignmentX(Component.CENTER_ALIGNMENT);
	    optionsButton.setAlignmentX(Component.CENTER_ALIGNMENT);
	    exitButton.setAlignmentX(Component.CENTER_ALIGNMENT);
	    
	    // Add action listeners (for when the buttons are clicked)
	    hostGameButton.addActionListener(this);
	    joinGameButton.addActionListener(this);
	    optionsButton.addActionListener(this);
	    exitButton.addActionListener(this);
	    
	    // "glue" creates whitespace between buttons
	    for(int i = 0; i < 10; i++)
	    	verticalBox.add(Box.createGlue());

	    // Add buttons to the vertical box
	    verticalBox.add(hostGameButton);
	    verticalBox.add(Box.createGlue());
	    verticalBox.add(joinGameButton);
	    verticalBox.add(Box.createGlue());
	    verticalBox.add(optionsButton);
	    verticalBox.add(Box.createGlue());
	    verticalBox.add(exitButton);
	    
	    // "glue" creates whitespace between buttons
	    for(int i = 0; i < 10; i++)
	    	verticalBox.add(Box.createGlue());
	    
	    // Create a JPanel to add the vertical box on
	    JPanel panel = new JPanel(new BorderLayout());
	    panel.add(verticalBox);
	    
	    // Set the background color of the panel
	    panel.setBackground(new Color(102, 171, 250));
	    
	    // Add the panel to the pane
	    pane.add(panel);
	}
	
	/**
	 * This method joins a game (instead of hosting it).
	 * 
	 * @throws IOException 
	 * @throws ClassNotFoundException 
	 */
	public void joinGame(String IP, int Port) throws IOException, ClassNotFoundException
	{
		// Create a new Game object
		connectionManager = new ConnectionManager(this, IP, Port);
		
		launchGameFrame();
	}
	
	/**
	 * This method starts the game hosting process.
	 * 
	 * @throws IOException
	 */
	public void hostGame() throws IOException
	{
		connectionManager = new ConnectionManager(this);
		
		launchGameFrame();
	}
	
	/**
	 * This method launches the game in a frame. 
	 */
	public void launchGameFrame()
	{
	    // Get the user's screen resolution
		Dimension screenDimensions = Toolkit.getDefaultToolkit().getScreenSize();
	    
		// Initialise the JFrame
		gameFrame = new JFrame();
		
		// Set the contents
	    gameFrame.setContentPane(connectionManager.getGameObject());
	    	    
	    // Set the game title
	    gameFrame.setTitle("Bomberman");
	    
		// Set the startup location and the size for the application
	    gameFrame.setBounds((screenDimensions.width / 2) - 400, (screenDimensions.height / 2) - 300, 800, 600);
	    
	    // Sets the size for the actual contents of the application (the application minus the title bar etc)
	    gameFrame.getContentPane().setPreferredSize(new Dimension(800, 600));
	    
	    // Don't allow resizing
	    gameFrame.setResizable(false);
	    
	    // Exit the application when the user closes the application
	    gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    
	    // pack forces the application to fit the requested size
	    gameFrame.pack();

	    // The key listener is called every time the user presses a key
	    gameFrame.addKeyListener(new KeyAdapter()
        {
	    	public void keyPressed(KeyEvent keyEvent)
            {
	    		// Call the keyEvent method on the Game class
	    		connectionManager.keyEvent(keyEvent);
            }
        });
	    
	    gameFrame.setVisible(true);
	    
	    // Hide the menu
	    this.setVisible(false);
	}
	
	/**
	 * This method opens the "Join game" menu option
	 */
	private void launchJoinGameFrame()
	{
		if(joinGameFrame == null)
		{
		    // Get the user's screen resolution
			Dimension screenDimensions = Toolkit.getDefaultToolkit().getScreenSize();
		    
			// Initialise the JFrame
			joinGameFrame = new JFrame();
		    
		    // Set the game title
			joinGameFrame.setTitle("Join game");
		    
			// Set the startup location and the size for the application
			joinGameFrame.setBounds((screenDimensions.width / 2) - 400, (screenDimensions.height / 2) - 300, 800, 600);
		    
		    // Sets the size for the actual contents of the application (the application minus the title bar etc)
			joinGameFrame.getContentPane().setPreferredSize(new Dimension(800, 600));
		    
		    // Don't allow resizing
			joinGameFrame.setResizable(false);
		    
		    // Exit the application when the user closes the application
			joinGameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		    
		    // pack forces the application to fit the requested size
			joinGameFrame.pack();
		}
		
		// Create a new Game object
		final JoinGame joinGame = new JoinGame(this);
		
	    // Set the contents to the Game object
		joinGameFrame.setContentPane(joinGame);
		
		// Make it visible
		joinGameFrame.setVisible(true);
	    
	    // Hide the menu
	    this.setVisible(false);
	}
	
	/**
	 * Returns the JFrame the game runs in
	 * 
	 * @return The JFrame
	 */
    public JFrame getGameFrame()
    {
    	return gameFrame;
    }
	
	/**
	 * This method returns the join game frame.
	 * 
	 * @return The join game frame
	 */
	public JFrame getJoinGameFrame()
	{
		return joinGameFrame;
	}

	/**
	 * Called 
	 */
	public void actionPerformed(ActionEvent e) 
	{
		// Host game button
		if(e.getSource() == hostGameButton)
		{
			try 
			{
				hostGame();
			} 
			catch (IOException e1) 
			{
				e1.printStackTrace();
			}	
		}
		
		else if(e.getSource() == joinGameButton)
		{
			launchJoinGameFrame();
		}
		
		// Exit button
		if(e.getSource() == exitButton)
		{
			// Only dispose of the gameFrame if it was actually created
			if(gameFrame != null)
			{
				gameFrame.setVisible(false);
				gameFrame.dispose();
			}
			
			this.setVisible(false);
			this.dispose();
		}
	}
	
	/**
	 * The entry point for the application.
	 * 
	 * @param params The parameters the jar was launched with.
	 */
  
	public static void main(String[] params) 
	{
		Main main = new Main();
		main.setVisible(true);
		
		PlayerManager.initialise(main);
	}
}
           